﻿using System.Collections.Generic;

using Storyteller.Framework.Graphics.Particles.Emitters;
using Storyteller.Framework.Math;

namespace Storyteller.Framework.Graphics.Particles
{
	public class ParticleEffect
	{
		public float Rotation 
		{ 
			get
			{ 
				return rotation;
			}
			set
			{
				rotation = value;
				foreach (ParticleEmitter emitter in Emitters)
				{
					emitter.WorldRotation = rotation;
				}
			}
		}

		public Vector2 Position
		{
			get
			{
				return position;
			}
			set
			{
				position = value;
				foreach (ParticleEmitter emitter in Emitters)
				{
					emitter.WorldPosition = position;
				}
			}
		}

		public bool Enabled { get; set; }

		public List<ParticleEmitter> Emitters { get; set; }

		public bool AutoDisable { get; set; }
		public bool AutoRemove { get; set; }
		public float AutoDisableTime { get; set; }

		public bool RemoveIfInactive { get; set; }
		public bool Remove { get; protected set; }

		public ParticleEffect()
		{
			Emitters = new List<ParticleEmitter>();
			Enabled = true;
		}

		public void Update(float deltaSeconds)
		{
			int activeParticleCount = 0;

			foreach (ParticleEmitter emitter in Emitters)
			{
				emitter.Enabled = Enabled;
				emitter.Update(deltaSeconds);
				activeParticleCount += emitter.ActiveParticleCount;
			}

			if (RemoveIfInactive && activeParticleCount == 0)
				Remove = true;

			if (AutoDisable)
			{
				lifeTime += deltaSeconds;
				if (lifeTime > AutoDisableTime)
				{
					Enabled = false;
					if (AutoRemove)
					{
						RemoveIfInactive = true;
					}
				}
			}
		}

		public void UpdateIncrementally(float deltaSeconds)
		{
			while (deltaSeconds > 0)
			{
				Update(INCREMENT_TIME);
				deltaSeconds -= INCREMENT_TIME;
			}
			Update(deltaSeconds);
		}

		public void FireOneShotEmitters()
		{
			foreach(ParticleEmitter emitter in Emitters)
			{
				if (emitter.IsSingleFire && !emitter.HasSingleFired)
				{
					emitter.EmitOneShotParticles();
				}
			}
		}

		public void Draw(SpriteBatch spriteBatch, Matrix4 cameraTransform)
		{
			foreach (ParticleEmitter emitter in Emitters)
			{
				emitter.Draw(spriteBatch, cameraTransform);
			}
		}

		public void Reset()
		{
			lifeTime = 0;
			Remove = false;
			Enabled = true;
			RemoveIfInactive = false;

			foreach (ParticleEmitter emitter in Emitters)
			{
				emitter.Reset();
			}
		}

		float lifeTime = 0;
		float rotation = 0;
		Vector2 position = Vector2.Zero;

		const float INCREMENT_TIME = 0.016f;
	}
}
